#include "stdafx.h"
#include "AlarmEventHandler.h"
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
#include <sstream> 

namespace Network
{
	AlarmEventHandler::AlarmEventHandler()
	{
		this->reactor = SelectReactor::instance();
		reactor->register_handler(this, READ_EVENT);
	}

	AlarmEventHandler::AlarmEventHandler(const SOCK_Stream &stream)
	{
		peerStream = stream;
	}

	void AlarmEventHandler::HandleEvent(HANDLE handle, EventType event_type)
	{
		switch( event_type )
		{
		case READ_EVENT || ACCEPT_EVENT :
			printf("AlarmEventHandler::HandleEvent => ACCEPT or READ event\n");
			handleRead(handle);
			break;

		case CLOSE_EVENT:
			peerStream.close();
			reactor->register_handler(this, CLOSE_EVENT);
			break;
		}
	}

	HANDLE AlarmEventHandler::GetHandle() 
	{
		return peerStream.GetHandle();
	}

	bool AlarmEventHandler::IsRunning()
	{
		return status;
	}

	void AlarmEventHandler::handleRead(HANDLE handle)
	{
		//get the message size
		u_char buffer[2];
		u_char msgSize;
		int result;
			
		result = peerStream.receive(buffer, sizeof(msgSize), 0 );
		msgSize = buffer[1];
			
		//Get the message
		int dataReceived = 0;
		u_char* message = (u_char*)malloc(sizeof(u_char)*msgSize);
		ZeroMemory(message, msgSize);
		dataReceived = peerStream.receive(message, msgSize, 0);

		// TODO concatenate buffer[0] and buffer[1] with char* message
		u_char buf_size =  sizeof(buffer[0]) + sizeof(buffer[1]) + sizeof(char)*msgSize;
		char* buf = (char*) malloc(buf_size);				
		ZeroMemory(buf, buf_size);

		buf[0] = buffer[0];
		buf[1] = buffer[1];

		for (u_int i = 0; i < (sizeof(u_char)*msgSize); i++) {
			buf[i+2] = message[i];
		}

		//result = peerStream.receive( input, sizeof(input), 0 );

		if( result > 0 )
		{
			AlarmEvent evt;
			//deserializeAlarmEvent((char*)buffer, &evt);

			if (deserializeAlarmEvent((char*)buf, &evt) != 0) {
				fprintf(stdout, "Error in deserialization of AlarmEvent!");
			}

			time_t timestamp;
			time(&(timestamp));
			AlarmEventItem alarmEventItem(evt, timestamp);
			//alarms.push_back(alarmEventItem);

			// sort the vector according to priority and pop off the back if it is larger than 10
			//std::sort(alarms.begin(), alarms.end(), AlarmEventItemPriorityComparer());
			//while (alarms.size() > 10) {
			///	alarms.pop_back();
			//}

			//cout << "Alarm count: " << alarms.size() << "\n";
			//for(u_int i = 0; i < alarms.size(); i++){
				char buffer[26];
				ctime_s(buffer, 26, &(alarmEventItem.timestamp));
				printf("Alarm =>\n\tPriority = %d;\n\ttime = %s\ttext = %s\n", alarmEventItem.event.priority, buffer, alarmEventItem.event.text.c_str());
				printf("------------------------------------------------\n\n");
			//}
		}
		else
		{
			peerStream.close();
			//reactor->RemoveHandler( this, CLOSE_EVENT );
			throw( "Client disconnected\n" );
		}
	}

	/*
	std::string AlarmEventHandler::handle(unsigned char* data)
	{
		AlarmEvent evt = AlarmEvent();
		// char* buffer = (char*) malloc(sizeof(data)); 
		if (0 != deserializeAlarmEvent((char*)data, &evt)) {
			fprintf(stdout, "Error in deserialization of AlarmEvent!");
		}

		//AlarmEvent evt = readAlarm(data);
		time_t timestamp;
		time(&(timestamp));
		AlarmEventItem alarmEventItem(evt, timestamp);
		alarms.push_back(alarmEventItem);

		// sort the vector according to priority and pop off the back if it is larger than 10
		std::sort(alarms.begin(), alarms.end(), AlarmEventItemPriorityComparer());
		while (alarms.size() > 10) {
			alarms.pop_back();
		}
		
		std::ostringstream out;
		out << "Alarm count: " << alarms.size() << "\n";
		for(u_int i = 0; i < alarms.size(); i++){
			char buffer[26];
			ctime_s(buffer, 26, &(alarms.at(i).timestamp));
			out << "Alarm => Priority = " << alarms.at(i).event.priority << " time = " << buffer << " text = " << alarms.at(i).event.text << "\n";
			
			
		}
		std::string str( out.str());
		return str;
	}
	*/
}